<template>
  <div class="div" :style="{ '--theme': theme }">
    <el-table
      :ref="refTable"
      v-loading="loading"
      class="table"
      :row-key="tableTree ? 'id' : undefined"
      :expand-row-keys="tableExpand"
      :tree-props="tableTree
        ? { children: 'children', hasChildren: 'isLeaf' }
        : undefined
      "
      :tooltip="true"
      :border="border"
      :size="size"
      :indent="indent"
      :lazy="lazy"
      :show-summary="showSummary"
      :summary-method="summaries"
      :default-expand-all="defaultExpandAll"
      element-loading-background="rgba(255, 255, 255, 0.8)"
      element-loading-text="数据正在加载中"
      element-loading-spinner="el-icon-loading"
      :data="tableData"
      :cell-style="cellStyle"
      :height="height || null"
      :default-sort="{ prop: 'id', order: null }"
      style="width: 100%"
      :load="lazy ? load : null"
      :span-method="method ? spanMethod : null"
      @sort-change="sortChange"
      @filter-change="handleFilterChange"
      @selection-change="handleSelectionChange"
      @row-click="rowClick"
      @expand-change="expandChange"
      @select-all="selectAll"
      @select="handleSelect"
      @current-change="handleCurrentRowChange"
      @header-dragend="handleHeaderDragEnd"
    >
      <template v-for="(item, index) in columns">
        <template
          v-if="item.hidden != false &&
            item.type !== 'slot' &&
            item.type != 'expand'
          "
        >
          <column :key="item.key ? item.key : index" :col="item">
            <template v-for="slot in Object.keys($scopedSlots)" #[slot]="scope">
              <slot :name="slot" v-bind="scope" />
            </template>
          </column>
        </template>
        <template v-if="item.type == 'expand'">
          <el-table-column
            :key="item.key ? item.key : index"
            :width="item.width"
            :label="item.label"
            :fixed="item.fixed ? item.fixed : false"
            type="expand"
          >
            <template slot-scope="scope">
              <slot :name="item.slotType" :row="scope.row" :index="scope.$index" />
            </template>
          </el-table-column>
        </template>

        <!-- solt 自定义列-->
        <template v-else-if="item.type === 'slot'">
          <el-table-column
            :key="item.key ? item.key : index"
            :width="item.width"
            :show-overflow-tooltip="true"
            :min-width="item.minWidth"
            :prop="item.prop"
            :label="item.label"
            :fixed="item.fixed ? item.fixed : false"
            :align="item.align ? item.align : 'center'"
            :render-header="item.renderHeader"
            :filters="item.filters"
            :filter-method="item.filterTag"
            filter-placement="bottom-end"
            :reserve-selection="item.reserveSelection"
            :type="item.colType"
          >
            <template slot-scope="scope">
              <slot :name="item.slotType" :row="scope.row" :index="scope.$index" />
            </template>
          </el-table-column>
        </template>
      </template>

      <template slot="empty">
        <el-image :src="NothingUrl" class="emptyImg" />
      </template>
    </el-table>
    <div
      v-if="total > 0"
      style="
          width: 100%;
          display: flex;
          align-items: center;
          justify-content: flex-end;
          margin-top: 0.375rem;
        "
    >
      <el-pagination
        :current-page="currentPage"
        background
        :page-sizes="pageSizes"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script>
import { treeToArray } from '@/utils'

import Column from './childRen/Column.vue'

export default {
  name: 'CommonTable',
  components: { Column },
  props: {
    // eslint-disable-next-line vue/require-default-prop
    amount: Function, // 自定义合计
    // eslint-disable-next-line vue/require-default-prop
    load: Function, // 自定义懒加载方法
    // eslint-disable-next-line vue/require-default-prop
    tableData: Array, // 表格数据
    tableTree: Boolean, // 是否开启树形表格
    lazy: Boolean, // 是否开启懒加载
    border: {
      type: Boolean,
      default: true
    }, // 表格边框开关
    // eslint-disable-next-line vue/require-default-prop
    columns: Array, // 表格头部
    // eslint-disable-next-line vue/require-default-prop
    loading: Boolean, // 表格加载中开关
    // eslint-disable-next-line vue/require-default-prop
    cellStyle: Function, // 列样式
    // eslint-disable-next-line vue/require-default-prop
    defaultExpandedKeys: Array, // 指定树展开行
    // eslint-disable-next-line vue/require-default-prop
    sortable: String, // 排序
    // 表格ref名
    refTable: {
      type: String,
      default: 'refTable'
    },
    // 表格高度
    height: {
      type: Number,
      default: 0
    },
    // 树结构节点缩进距离
    indent: {
      type: Number,
      default: 16
    },
    // 当前页
    currentPage: {
      type: Number,
      default: 1
    },
    // 每页显示多少条
    pageSize: {
      type: Number,
      default: 10
    },
    // 条数切换数组
    pageSizes: {
      type: Array,
      default: () => {
        return [10, 30, 50, 100]
      }
    },
    // 总共多少条
    total: {
      type: Number,
      default: 0
    },
    // 动态控制表格展开的列
    // eslint-disable-next-line vue/require-default-prop
    tableExpand: {
      type: Array
    },
    // 是否默认展开所有行
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    // 是否需要合并表格
    method: {
      type: Boolean,
      default: false
    },
    // 需合并表格的列下标
    columnKey: {
      type: String,
      default: ''
    },
    // 表尾合计
    showSummary: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      NothingUrl: '', // 暂无数据图片
      keyValue: null // 用于表格合并时的暂存变量
    }
  },
  computed: {
    // 主题色
    theme() {
      return this.$store.state.settings.theme
    },
    // 布局大小
    size() {
      return this.$store.state.app.size
    }
  },
  watch: {
    tableExpand: {
      handler() {
        const $table = this.$refs.refTable
        const result = this.getChildRens(this.tableData)
        // 将树形结构数据扁平化
        const extractResult = treeToArray(JSON.parse(JSON.stringify(this.tableData)), 'children')
        console.log(extractResult)
        // 遍历数组与需要闭合的列数组对比
        extractResult.map((item) => {
          if (result.includes(item.id)) {
            $table.toggleRowExpansion(item, false)
          } else {
            $table.toggleRowExpansion(item, true)
          }
        })
      },
      deep: true
    },
    tableData: {
      handler() {
        this.keyValue = undefined
        this.numbers = 0
      },
      deep: true
    }
  },
  created() {
    const module = import.meta.globEager('@/assets/svg/Nothing.svg')
    this.NothingUrl = module['/src/assets/svg/Nothing.svg'].default
  },
  methods: {
    // 自定义合计方法
    summaries(param) {
      return this.amount(param)
    },
    // 合并方法
    spanMethod({ row, column }) {
      if (column.property === this.columnKey) {
        let i = 0
        let num = 0
        if (this.keyValue !== row[this.columnKey]) {
          while (i < this.tableData.length) {
            if (this.tableData[i][this.columnKey] === row[this.columnKey]) {
              num++
            }
            i++
          }
          this.keyValue = row[this.columnKey]
        } else {
          num = 0
        }
        return {
          rowspan: num,
          colspan: 1
        }
      }
    },
    // 表单按钮事件转发
    handlerClick(btn) {
      this.$emit('handlerClick', btn)
    },
    // 操作列按钮事件
    handleButton(methods, row, event) {
      this.$emit('handleButton', {
        methods: methods,
        row: row
      })
    },
    // 筛选条件改变事件
    handleFilterChange(filters) {
      this.$emit('handleFilterChange', filters)
    },

    // 多选点击事件
    handleSelectionChange(filters) {
      this.$emit('handleSelectionChange', filters)
    },
    // checkbox点击事件
    handleSelect(selection, row) {
      this.$emit('handleSelect', selection, row)
    },
    // 全选点击事件
    selectAll(e) {
      this.$emit('selectAll', e)
    },
    // 排序改变事件  须设置sortable为true 并且表格的@sort-change事件有值
    sortChange(filters) {
      this.$emit('sortChange', filters)
    },
    // row点击事件
    rowClick(type, value, event) {
      this.$emit('rowClick', type, value)
    },
    // 每页显示多少条改变事件
    handleSizeChange(val) {
      this.$emit('handleSizeChange', val)
    },
    // 当前页发生改变事件
    handleCurrentChange(val) {
      this.$emit('handleCurrentChange', val)
    },
    // 行展开或闭合时触发该事件
    expandChange(val, expanded) {
      this.$emit('expandChange', { val, expanded })
    },
    // 获取需要闭合的列
    getChildRens(arr) {
      const result = []
      arr.map((item) => {
        if (!this.tableExpand.includes(item.id)) result.push(item.id)

        if (Object.prototype.hasOwnProperty.call(item, 'children')) {
          const child = this.getChildRens(item.children)
          result.push(...child)
        }
      })

      return result
    },
    // 当前选中行改变事件
    handleCurrentRowChange(val) {
      this.$emit('handleCurrentRowChange', val)
    },
    // 处理列宽拖动完成事件
    handleHeaderDragEnd() {
      this.$nextTick(() => {
        console.log(this.$refs.refTable)
        this.$refs.refTable.doLayout()
      })
    }
  }
}
</script>
<style lang="scss" scoped>

::v-deep .el-pagination {
  .is-background {
    width: 100%;
  }

  .number {
    border-radius: 20% !important;
  }

  .el-icon {
    background: none !important;
  }

  .el-pagination__jump {
    margin-left: 4px !important;
  }

  .el-input__inner:last-child {
    border: 0.0625rem solid var(--theme) !important;
    border-radius: 16% !important;
  }

  .active {
    background: var(--theme) !important;
  }
}

.actionCell {
  .cell {
    display: flex;
  }
}

.emptyImg {
  width: 200px;
  margin-top: -100px;
  left: 50%;
  position: absolute;
  top: 50%;
  margin-left: -100px;
}

.emptyTitle {
  margin-top: -25px;
  color: rgb(74, 74, 74, 0.5);
}

.el-pagination {
  float: right !important;
}

::v-deep .el-table thead th {
  background-color: #f3f3f3 !important;
}

::v-deep .el-table--border .el-table__cell {
  border-right: 1px solid #dfe6ec;
}

::v-deep .el-table--enable-row-transition .el-table__body td {
  transition: none;
}

::v-deep .el-table .choice-row>td {
  background: #aacbff !important;

  &:hover {
    background: #aacbff !important;
    background-color: #aacbff !important;
  }
}

// ::v-deep .el-table__body-wrapper {
//   &::-webkit-scrollbar {
//     height: 8px;
//     width: 8px;
//   }

//   &::-webkit-scrollbar-track {
//     border-radius: 8px;
//     background-color: #fff;
//   }

//   &::-webkit-scrollbar-thumb {
//     border-radius: 8px;
//     background-color: #ccc;
//   }

//   &::-webkit-scrollbar-thumb:hover {
//     border-radius: 8px;
//     background-color: var(--theme);
//   }
// }

// ::v-deep .el-scrollbar_wrap::-webkit-scrollbar {
//   width: 8px !important;
//   height: 8px !important;
// }

// 解决表格固定列问题
::v-deep .el-table__fixed,
.el-table__fixed-right {
  height: calc(100% - 7px) !important;
  box-shadow: -5px -2px 10px rgba(0, 0, 0, 0.12) !important;

  .el-table__fixed-body-wrapper {
    height: calc(100% - 36px) !important;
  }
}
// 当表格没有滚动条时
::v-deep .el-table__body-wrapper.is-scrolling-none~.el-table__fixed-right {
  height: 100% !important;
  bottom: 0 !important;
  box-shadow: none !important;
}
</style>
